package com.macro.mall.storage.config;

import com.macro.mall.common.enums.SourceTypeEnum;
import com.macro.mall.storage.*;
import net.anumbrella.seaweedfs.core.FileSource;
import net.anumbrella.seaweedfs.core.FileTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

/**
 * @author 郎
 */
@Configuration
@EnableConfigurationProperties(StorageProperties.class)
public class StorageAutoConfiguration {
    private static final Logger logger = LoggerFactory.getLogger(StorageAutoConfiguration.class);
    private final StorageProperties properties;

    public StorageAutoConfiguration(StorageProperties properties) {
        this.properties = properties;
    }

    @Bean
    public StorageService storageService() {
        StorageService storageService = new StorageService();
        String active = this.properties.getActive();
        logger.info("当前存储服务使用的是：" + active);
        storageService.setActive(active);
        SourceTypeEnum storageEnum = SourceTypeEnum.valueOf(active.toUpperCase());
        switch (storageEnum) {
            case LOCAL:
                storageService.setStorage(localStorage());
                break;
            case ALIYUN:
                storageService.setStorage(aliyunStorage());
                break;
            case TENCENT:
                storageService.setStorage(tencentStorage());
                break;
            case QINIU:
                storageService.setStorage(qiniuStorage());
                break;
            case MINIO:
                storageService.setStorage(minioStorage());
                break;
            case SEAWEEDFS:
                storageService.setStorage(seaWeedStorage());
                break;
            case HUAWEI:
                storageService.setStorage(huaweiStorage());
                break;
            default:
                throw new RuntimeException("当前存储模式 " + active + " 不支持");
        }
        return storageService;
    }

    @Bean
    @ConditionalOnProperty(value = "storage.active", havingValue = "seaweedfs")
    public SeaWeedStorage seaWeedStorage() {
        SeaWeedStorage seaWeedStorage = new SeaWeedStorage();
        FileSource fileSource = new FileSource();
        StorageProperties.Seaweedfs seaweedfs = this.properties.getSeaweedfs();
        fileSource.setHost(seaweedfs.getHost());
        fileSource.setPort(seaweedfs.getPort());
        fileSource.setConnectionTimeout(10 * 1000);
        try {
            fileSource.startup();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        seaWeedStorage.setFileTemplate(new FileTemplate(fileSource.getConnection()));
        seaWeedStorage.setHost(seaweedfs.getHost());
        seaWeedStorage.setPort(seaweedfs.getPort());
        seaWeedStorage.setPublicDomain(seaweedfs.getPublicDomain());
        return seaWeedStorage;
    }

    @Bean
    @ConditionalOnProperty(value = "storage.active", havingValue = "local")
    public LocalStorage localStorage() {
        LocalStorage localStorage = new LocalStorage();
        StorageProperties.Local local = this.properties.getLocal();
        localStorage.setAddress(local.getAddress());
        localStorage.setStoragePath(local.getStoragePath());
        return localStorage;
    }

    @Bean
    @ConditionalOnProperty(value = "storage.active", havingValue = "minio")
    public MinioStorage minioStorage() {
        MinioStorage minioStorage = new MinioStorage();
        StorageProperties.Minio minio = this.properties.getMinio();
        minioStorage.setAccessKey(minio.getAccessKey());
        minioStorage.setSecretKey(minio.getSecretKey());
        minioStorage.setBucketName(minio.getBucketName());
        minioStorage.setEndpoint(minio.getEndpoint());
        return minioStorage;
    }

    @Bean
    @ConditionalOnProperty(value = "storage.active", havingValue = "huawei")
    public HuaweiStorage huaweiStorage() {
        HuaweiStorage huaweiStorage = new HuaweiStorage();
        StorageProperties.Huawei huawei = this.properties.getHuawei();
        huaweiStorage.setAccessKey(huawei.getAccessKey());
        huaweiStorage.setSecretKey(huawei.getSecretKey());
        huaweiStorage.setBucketName(huawei.getBucketName());
        huaweiStorage.setEndpoint(huawei.getEndpoint());
        return huaweiStorage;
    }

    @Bean
    @ConditionalOnProperty(value = "storage.active", havingValue = "aliyun")
    public AliyunStorage aliyunStorage() {
        AliyunStorage aliyunStorage = new AliyunStorage();
        StorageProperties.Aliyun aliyun = this.properties.getAliyun();
        aliyunStorage.setAccessKeyId(aliyun.getAccessKeyId());
        aliyunStorage.setAccessKeySecret(aliyun.getAccessKeySecret());
        aliyunStorage.setBucketName(aliyun.getBucketName());
        aliyunStorage.setEndpoint(aliyun.getEndpoint());
        return aliyunStorage;
    }

    @Bean
    @ConditionalOnProperty(value = "storage.active", havingValue = "tencent")
    public TencentStorage tencentStorage() {
        TencentStorage tencentStorage = new TencentStorage();
        StorageProperties.Tencent tencent = this.properties.getTencent();
        tencentStorage.setSecretId(tencent.getSecretId());
        tencentStorage.setSecretKey(tencent.getSecretKey());
        tencentStorage.setBucketName(tencent.getBucketName());
        tencentStorage.setRegion(tencent.getRegion());
        return tencentStorage;
    }

    @Bean
    @ConditionalOnProperty(value = "storage.active", havingValue = "qiniu")
    public QiniuStorage qiniuStorage() {
        QiniuStorage qiniuStorage = new QiniuStorage();
        StorageProperties.Qiniu qiniu = this.properties.getQiniu();
        qiniuStorage.setAccessKey(qiniu.getAccessKey());
        qiniuStorage.setSecretKey(qiniu.getSecretKey());
        qiniuStorage.setBucketName(qiniu.getBucketName());
        qiniuStorage.setEndpoint(qiniu.getEndpoint());
        return qiniuStorage;
    }
}
